﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Bling.Core;
using Bling.WPF;
using Bling.Util;
using Bling.Graphics;
namespace Bling.Tutorial {
  public class MetaBall : Canvas {
    public MetaBall() {
      CanvasBl canvas = this;
      new CanvasBl(canvas) {
        Size = canvas.Size,
        LeftTop = new Point(0, 0),
        Background = Brushes.Black,
        Effect = {
          Custom = (input, uv) => {
            Random r = new Random();
            ColorBl[] colors = new ColorBl[] {
                Colors.Red, 
                Colors.Blue, 
                Colors.LimeGreen, 
                Colors.Yellow, 
            };
            RgbBl color = Colors.Black.Bl().ScRGB;
            DoubleBl metaball = 0;
            for (int i = 0; i < 7; i++) {
              var primary = colors[i % colors.Length];
              var thumb = new ThumbBl(canvas) {
                Background = primary,
                ZIndex = 1,
                CenterPosition = canvas.CenterSize - new Double2Bl(150, 150) +
                                 r * new Double2Bl(300, 300),
                CanDrag = true,
              };
              Double2Bl point = thumb;
              EllipseBl circle = new EllipseBl(canvas) {
                CenterPosition = point,
                Stroke = { Thickness = 0, Brush = Brushes.Black },
                ZIndex = 0,
                Size = new Double2Bl(100, 100),
                Fill = Brushes.Transparent,
              };
              Double2Bl v = (uv * canvas.Size - point).Square;
              DoubleBl at = 3d / (v.X + v.Y);
              color += ((circle.IsMouseOver | thumb.IsMouseOver | thumb.IsDragging).Condition(Colors.White.Bl().ScRGB, primary.ScRGB)) * at;
              metaball += at;
            }
            RgbBl useColor = color / metaball;
            DoubleBl edge = 1.0 - ((metaball - .0014) / .0002).Saturate;
            return edge.Lerp(useColor, 1d - useColor);
          }
        },
      };
    }
    public Tex2D MetaBalls(IListBl<Double2Bl> Points, IListBl<ColorBl> BallColors) {
      return new Tex2D(UV => {
        ColorBl color = Colors.Black;
        DoubleBl metaball = 0;
        for (int i = 0; i < Points.Count; i++) {
          Double2Bl p = Points[i];
          Double2Bl v = (UV - Points[i]);
          v = v * v;
          var at = 3d / (v.X + v.Y);
          color += BallColors[i] * at;
          metaball += at;
        }
        var useColor = color / metaball;
        return (metaball > .0016).Condition(useColor, Colors.White);
      });
    }


  }

}
